package com.effective.java.hashCode;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class GoodHashCode01 {

	public static void main(String[] args) {

		Set<PhoneNumber> phoneNumberSet = new HashSet<PhoneNumber>();
		List<PhoneNumber> phoneNumberList = new ArrayList<PhoneNumber>();
		phoneNumberSet.add(new PhoneNumber((short) 100, (short) 200, (short) 300));

		System.out.println("phoneNumberSet.contains(new PhoneNumber((short) 100, (short) 200, (short) 300)) = "
				+ phoneNumberSet.contains(new PhoneNumber((short) 100, (short) 200, (short) 300)));

		phoneNumberList.add(new PhoneNumber((short) 100, (short) 200, (short) 300));
		System.out.println("phoneNumberList.contains(new PhoneNumber((short) 100, (short) 200, (short) 300)) = "
				+ phoneNumberList.contains(new PhoneNumber((short) 100, (short) 200, (short) 300)));
	}

	private static final class PhoneNumber {

		private final short areaCode;
		private final short prefix;
		private final short lineNumber;

		private Integer derivedHashCode;

		public PhoneNumber(short areaCode, short prefix, short lineNumber) {

			this.areaCode = areaCode;
			this.prefix = prefix;
			this.lineNumber = lineNumber;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public boolean equals(Object o) {

			if (this == o) {
				return true;
			}

			if (!(o instanceof PhoneNumber)) {
				return false;
			}

			PhoneNumber number = (PhoneNumber) o;
			return this.areaCode == number.areaCode && this.prefix == number.prefix
					&& this.lineNumber == number.lineNumber;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public int hashCode() {

			if (this.derivedHashCode == null) {
				int result = 17;
				result = 31 * result + areaCode;
				result = 31 * result + prefix;
				result = 31 * result + lineNumber;
				this.derivedHashCode = result;
			}
			return this.derivedHashCode;
		}
	}
}
